package com.demo.project_template.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.demo.project_template.base.im.service.YxService;
import com.demo.project_template.base.pay.wxpay.service.WechatJSAPIGetMsgService;
import com.demo.project_template.base.pay.wxpay.vo.DecryptWeChartMsgVO;
import com.demo.project_template.constant.AuthenticationConstants;
import com.demo.project_template.constant.UserConstants;
import com.demo.project_template.entity.LoginUser;
import com.demo.project_template.entity.SysUser;
import com.demo.project_template.entity.User;
import com.demo.project_template.exception.ErrorCodeException;
import com.demo.project_template.mapper.UserMapper;
import com.demo.project_template.service.LoginService;
import com.demo.project_template.util.CheckEmptyUtil;
import com.demo.project_template.util.CommonUtil;
import com.demo.project_template.util.JwtUtil;
import com.demo.project_template.util.RedisUtil;
import com.demo.project_template.vo.request.user.UserLoginVO;
import com.demo.project_template.vo.response.LoginResponseVo;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.UUID;

/**
 * @author yyl25
 */
@Slf4j
@Service
public class LoginServiceImpl implements LoginService {
    @Resource
    private RedisUtil redisUtil;
    @Resource
    private UserMapper userMapper;
    @Resource
    private YxService yxService;
    @Resource
    private AuthenticationManager authenticationManager;

    @Override
    public LoginResponseVo userLogin(UserLoginVO userLoginVO) {
        //暂时就只按照验手机证码登录做
        String captcha = redisUtil.get(UserConstants.CAPTCHA_PREFIX + userLoginVO.getPhoneNumber());
        if (null == captcha){
            throw new ErrorCodeException("验证码已过期");
        }
        if (!captcha.equals(userLoginVO.getCaptcha())){
            throw new ErrorCodeException("验证码输入错误");
        }
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getPhoneNumber, userLoginVO.getPhoneNumber()));
        if (user == null){
            //进入注册流程
            user = new User();
            if (userLoginVO.getInvitersCode()!=null){
                User inviter = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getInvitationCode, userLoginVO.getInvitersCode()));
                if (inviter==null){
                    throw new ErrorCodeException("邀请码填写错误，未找到对应用户");
                }
                user.setInviterId(inviter.getId());
            }
            user.setPhoneNumber(userLoginVO.getPhoneNumber());
            user.setIsDelete("0");
            user.setFansCount(0L);
            user.setViewCount(0L);
            user.setInvitationCode(UUID.randomUUID().toString());
            //im系统的account_id使用的是本系统的手机号
            String token = yxService.register(user.getPhoneNumber());
            user.setImToken(token);
            userMapper.insert(user);
        }
        LoginResponseVo loginResponseVo = new LoginResponseVo(user, 1);
        String redisUserTokenKey = AuthenticationConstants.USER_LOGIN_TOKEN+ user.getId();
        redisUtil.set(redisUserTokenKey, loginResponseVo.getToken(),60*60*24*30);
        return loginResponseVo;
    }

    @Override
    public void sendCaptcha(String phoneNumber) {
        //todo 接入短信
        String code = CommonUtil.creatCode();
        redisUtil.set(UserConstants.CAPTCHA_PREFIX+phoneNumber,code,120);
        System.out.println(phoneNumber+"的验证码为:"+code);
    }

    @Override
    public LoginResponseVo sysLogin(SysUser user) {
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUsername(),user.getPassword());
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        if(Objects.isNull(authenticate)){
            throw new ErrorCodeException(500,"用户名或密码错误");
        }
        LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
        Long userId = loginUser.getUser().getId();
        LoginResponseVo loginResponseVo = new LoginResponseVo();
        loginResponseVo.setUserId(userId);
        loginResponseVo.setType(0);
        loginResponseVo.setToken(JwtUtil.createJWT(userId.toString()));
        String redisUserTokenKey = AuthenticationConstants.BACKSTAGE_USER_LOGIN_TOKEN+ userId;
        //todo 后台登录考虑存token还是存对象
        redisUtil.set(redisUserTokenKey, JSON.toJSONString(loginUser));
        return loginResponseVo;
    }

    @Override
    public void logout() {
        redisUtil.del(AuthenticationConstants.BACKSTAGE_USER_LOGIN_TOKEN+JwtUtil.getUserId());
    }

}
